#ifndef _IRQ_H
#define _IRQ_H

#include <arch/irq.h>

enum irqreturn {
    IRQ_NONE        = (0 << 0),
    IRQ_HANDLED     = (1 << 0),
};

#define IRQS_EDGE_RISING	(1 << 0)
#define IRQS_EDGE_FAILING	(1 << 1)
#define IRQS_EDGE_BOTH		(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define	IRQS_LEVEL_HIGH		(1 << 2)
#define IRQS_LEVEL_LOW		(1 << 3)
#define IRQS_LEVEL_MASK		(IRQS_LEVEL_LOW | IRQS_LEVEL_HIGH)
#define IRQS_SENSE_MASK		(0xf)
#define IRQS_MASKED			(1 << 4)
#define IRQS_INPROGRESS		(1 << 5)
#define IRQS_PENDING		(1 << 6)

#define IRQF_NOREQUEST			(1 << 0)
#define IRQF_SET_TYPE_MASKED	(1 << 1)
#define IRQF_DISABLE			(1 << 2)
#define IRQF_VALID				(0 << 0)

#define IRQ_TYPE_NONE			(0) 
#define IRQ_TYPE_EDGE_RISING    (IRQS_EDGE_RISING)
#define IRQ_TYPE_EDGE_FALLING	(IRQS_EDGE_FAILING) 
#define IRQ_TYPE_EDGE_BOTH		(IRQS_EDGE_BOTH)
#define IRQ_TYPE_LEVEL_HIGH		(IRQS_LEVEL_HIGH)
#define IRQ_TYPE_LEVEL_LOW		(IRQS_LEVEL_LOW)
#define IRQ_TYPE_LEVEL_MASK		(IRQS_LEVEL_MASK)
#define IRQ_TYPE_SENSE_MASK		(IRQS_SENSE_MASK)

typedef void (*irq_flow_handler_t)(unsigned int irq, struct irq_desc *desc);

struct irq_chip {
    void (*irq_ack)(struct irq_chip *chip);
    void (*irq_mask)(struct irq_chip *chip);
    void (*irq_mask_ack)(struct irq_chip *chip);
    void (*irq_unmask)(struct irq_chip *chip);
	int  (*irq_set_type)(struct irq_chip *chip, unsigned int type);
};

typedef int (*irq_handler_t)(unsigned int irq, void *priv);

struct irqaction {
	irq_handler_t handler;
	void *priv;
	struct irqaction *next;
};

struct irq_desc {
	unsigned int		irq;
	unsigned int		state;
	unsigned int		flags;
	struct irq_chip		*chip;
	irq_flow_handler_t  handle_irq;
	struct irqaction	*action; 
};

#define local_irq_enable()			do { arch_local_irq_enable(); } while (0)
#define local_irq_disable()			do { arch_local_irq_disable(); } while (0)
#define local_irq_save(flags)		do { flags = arch_local_irq_save(); } while (0)
#define local_irq_restore(flags)	do { arch_local_irq_restore(flags); } while (0)

#define __exception __attribute__((section(".exception.text")))

#endif /* _IRQ_H */

